﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

//对于订单：添加、删除、修改、查询 ->订单号、商品名称、客户、订单金额等，每个方法测试用例
//主要的类：Order\OrderDetails\OrderService,订单数据进行保存在OrderService中的List
//program可以调用各种OrderService操作

//商品类：
public class Product
{
    public string ID { get; set; }//商品号
    public string NAME { get; set; }//商品名称
    public decimal Price { get; set; }//价格
    public Product(string id, string name, decimal price)
    { ID = id;
        NAME = name;
        Price = price;
    }
    public override string ToString()
    {
        return $"Product ID:{ID}, Product Name: {NAME},Product price:{Price:C}";
    }
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;
        Product other = (Product)obj;
        return ID == other.ID && NAME == other.NAME && Price == other.Price;
    }
    public override int GetHashCode()
    {
        return (ID,NAME,Price).GetHashCode();
    }
}

//客户类：
public class Customer
{
    public string ID { get; set; }
    public string Name { get; set; }
    public string Contact { get; set; }
    public Customer(string id, string name, string contact)
    { ID = id;
      Name = name;
        Contact = contact;
    }
    public override string ToString()
    {
        return $"Customer ID:{ID},Customer Name:{Name},Customer Contact:{Contact}";
    }
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;
        Customer other = (Customer)obj;
        return ID == other.ID && Name == other.Name && Contact == other.Contact;
    }
    public override int GetHashCode()
    {
        return (ID, Name, Contact).GetHashCode();
    }
}


//订单明细：
public class OrderDetail
{
    public Product Product { get; set; }
    public int Quantity { get; set; }
    public decimal TotalAmount =>Product.Price * Quantity;

    public OrderDetail(Product product, int quantity
      )
    { Product = product;
      Quantity = quantity;
    }
    public override string ToString()
    {
        return $"{Product},Quantity:{Quantity},ToatalAmount:{TotalAmount:C}";
    }
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;
        OrderDetail other = (OrderDetail)obj;
        return Product.Equals(other.Product) && Quantity == other.Quantity;
    }
    public override int GetHashCode()
    {
        return (Product,Quantity).GetHashCode();
    }
}

//订单类：
public class Order: IComparable<Order>
{
    public string OrderId { get; set; }
    public Customer Customer { get; set; }
    public DateTime OrderDate { get; set; }
    public List<OrderDetail> OrderDetails { get; set; }
    public decimal TotalAmount => OrderDetails.Sum(od => od.TotalAmount);

    public Order(string orderId, Customer customer, DateTime orderDate)
    {
        OrderId = orderId;
        Customer = customer;
        OrderDate = orderDate;
        OrderDetails = new List<OrderDetail>();
    }

    //添加订单详情
    public void AddDetail(OrderDetail detail)
    {
        if (OrderDetails.Contains(detail))
        {
            throw new ArgumentException("Order detail already exists.");
        }
        OrderDetails.Add(detail);
    }

    //删除订单详情
    public void RemoveDetail(Product product)
    {
        var detail = OrderDetails.FirstOrDefault(od => od.Product.Equals(product));
        if (detail == null)
        {
            throw new ArgumentException("Product not found in order details.");
        }
        OrderDetails.Remove(detail);
    }

    public override string ToString()
    {
        string details = string.Join("\n  ", OrderDetails.Select(od => od.ToString()));
        return $"Order ID: {OrderId}, Date: {OrderDate:yyyy-MM-dd}\n" +
               $"Customer: {Customer}\n" +
               $"Order Details:\n  {details}\n" +
               $"Total Order Amount: {TotalAmount:C}";
    }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        Order other = (Order)obj;
        return OrderId == other.OrderId;
    }

    public override int GetHashCode()
    {
        return OrderId.GetHashCode();
    }

    public int CompareTo(Order other)
    {
        if (other == null) return 1;
        return OrderId.CompareTo(other.OrderId);
    }
}

//订单服务类：
public class OrderService
{
    private List<Order> orders = new List<Order>();

    // 添加订单
    public void AddOrder(Order order)
    {
        if (orders.Contains(order))
        {
            throw new ArgumentException("Order already exists.");
        }
        orders.Add(order);
    }

    // 删除订单
    public void RemoveOrder(string orderId)
    {
        var order = orders.FirstOrDefault(o => o.OrderId == orderId);
        if (order == null)
        {
            throw new ArgumentException($"Order with ID {orderId} not found.");
        }
        orders.Remove(order);
    }

    // 修改订单
    public void ModifyOrder(Order modifiedOrder)
    {
        var existingOrder = orders.FirstOrDefault(o => o.OrderId == modifiedOrder.OrderId);
        if (existingOrder == null)
        {
            throw new ArgumentException($"Order with ID {modifiedOrder.OrderId} not found.");
        }

        orders.Remove(existingOrder);
        orders.Add(modifiedOrder);
    }

    // 查询所有订单
    public List<Order> GetAllOrders()
    {
        return orders.OrderBy(o => o.TotalAmount).ToList();
    }

    // 按订单ID查询
    public List<Order> QueryByOrderId(string orderId)
    {
        var query = orders
            .Where(o => o.OrderId.Contains(orderId))
            .OrderBy(o => o.TotalAmount)
            .ToList();

        if (!query.Any())
        {
            throw new ArgumentException($"No orders found with ID containing '{orderId}'.");
        }

        return query;
    }

    // 按商品名称查询
    public List<Order> QueryByProductName(string productName)
    {
        var query = orders
            .Where(o => o.OrderDetails.Any(od => od.Product.NAME.Contains(productName)))
            .OrderBy(o => o.TotalAmount)
            .ToList();

        if (!query.Any())
        {
            throw new ArgumentException($"No orders found containing product '{productName}'.");
        }

        return query;
    }

    // 按客户查询
    public List<Order> QueryByCustomer(string customerName)
    {
        var query = orders
            .Where(o => o.Customer.Name.Contains(customerName))
            .OrderBy(o => o.TotalAmount)
            .ToList();

        if (!query.Any())
        {
            throw new ArgumentException($"No orders found for customer '{customerName}'.");
        }

        return query;
    }

    // 按订单金额范围查询
    public List<Order> QueryByAmountRange(decimal minAmount, decimal maxAmount)
    {
        var query = orders
            .Where(o => o.TotalAmount >= minAmount && o.TotalAmount <= maxAmount)
            .OrderBy(o => o.TotalAmount)
            .ToList();

        if (!query.Any())
        {
            throw new ArgumentException($"No orders found with amount between {minAmount:C} and {maxAmount:C}.");
        }

        return query;
    }

    // 排序订单
    public void SortOrders(Comparison<Order> comparison = null)
    {
        if (comparison == null)
        {
            orders.Sort(); // 使用默认的IComparable实现
        }
        else
        {
            orders.Sort(comparison);
        }
    }

    // 导出订单到文件
    public void ExportToFile(string filePath)
    {
        try
        {
            System.IO.File.WriteAllText(filePath, string.Join("\n\n", orders.Select(o => o.ToString())));
        }
        catch (Exception ex)
        {
            throw new Exception($"Failed to export orders: {ex.Message}");
        }
    }

    // 从文件导入订单
    public void ImportFromFile(string filePath)
    {
        throw new NotImplementedException("Import functionality not implemented in this example.");
    }
}

//主程序
namespace OrderManagement
{
    internal class Program
    {//初始化订单服务：
        static OrderService orderService = new OrderService();
        //商品类列表
        static List<Product> products = new List<Product>();
        //客户类列表
        static List<Customer> customers = new List<Customer>();
        static void Main(string[] args)
        { // 初始化一些测试数据
            InitializeTestData();

            while (true)
            {
                //输出选择信息：1
                Console.WriteLine("\n=== Order Management System ===");
                Console.WriteLine("1. Add Order");
                Console.WriteLine("2. Remove Order");
                Console.WriteLine("3. Modify Order");
                Console.WriteLine("4. Query Orders");
                Console.WriteLine("5. List All Orders");
                Console.WriteLine("6. Sort Orders");
                Console.WriteLine("7. Export Orders to File");
                Console.WriteLine("8. Exit");
                Console.Write("Please select an option: ");

                if (!int.TryParse(Console.ReadLine(), out int choice))
                {
                    Console.WriteLine("Invalid input. Please enter a number.");
                    continue;
                }

                try
                {
                    switch (choice)
                    {
                        case 1:
                            AddOrder();
                            break;
                        case 2:
                            RemoveOrder();
                            break;
                        case 3:
                            ModifyOrder();
                            break;
                        case 4:
                            QueryOrders();
                            break;
                        case 5:
                            ListAllOrders();
                            break;
                        case 6:
                            SortOrders();
                            break;
                        case 7:
                            ExportOrders();
                            break;
                        case 8:
                            return;
                        default:
                            Console.WriteLine("Invalid option. Please try again.");
                            break;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                }
            }
        }
        static void InitializeTestData()
        {
            // 添加一些产品和客户
            products.Add(new Product("P001", "Laptop", 999.99m));
            products.Add(new Product("P002", "Mouse", 19.99m));
            products.Add(new Product("P003", "Keyboard", 49.99m));
            products.Add(new Product("P004", "Monitor", 199.99m));

            customers.Add(new Customer("C001", "John Doe", "john@example.com"));
            customers.Add(new Customer("C002", "Jane Smith", "jane@example.com"));
            customers.Add(new Customer("C003", "Bob Johnson", "bob@example.com"));
        }

        static void AddOrder()
        {
            Console.WriteLine("\n--- Add New Order ---");

            // 选择客户
            Console.WriteLine("Available Customers:");
            for (int i = 0; i < customers.Count; i++)
            {
                Console.WriteLine($"{i + 1}. {customers[i]}");
            }
            Console.Write("Select customer (number): ");
            int custIndex = int.Parse(Console.ReadLine()) - 1;
            var customer = customers[custIndex];

            // 创建订单
            Console.Write("Enter Order ID: ");
            string orderId = Console.ReadLine();
            var order = new Order(orderId, customer, DateTime.Now);

            // 添加订单明细
            bool addMore = true;
            while (addMore)
            {
                Console.WriteLine("\nAvailable Products:");
                for (int i = 0; i < products.Count; i++)
                {
                    Console.WriteLine($"{i + 1}. {products[i]}");
                }
                Console.Write("Select product (number): ");
                int prodIndex = int.Parse(Console.ReadLine()) - 1;
                var product = products[prodIndex];

                Console.Write("Enter quantity: ");
                int quantity = int.Parse(Console.ReadLine());

                order.AddDetail(new OrderDetail(product, quantity));

                Console.Write("Add another product? (y/n): ");
                addMore = Console.ReadLine().ToLower() == "y";
            }

            orderService.AddOrder(order);
            Console.WriteLine("Order added successfully.");
        }

        static void RemoveOrder()
        {
            Console.WriteLine("\n--- Remove Order ---");
            Console.Write("Enter Order ID to remove: ");
            string orderId = Console.ReadLine();

            orderService.RemoveOrder(orderId);
            Console.WriteLine("Order removed successfully.");
        }

        static void ModifyOrder()
        {
            Console.WriteLine("\n--- Modify Order ---");
            Console.Write("Enter Order ID to modify: ");
            string orderId = Console.ReadLine();

            // 查找现有订单
            var existingOrders = orderService.QueryByOrderId(orderId);
            if (existingOrders.Count > 1)
            {
                Console.WriteLine("Multiple orders found. Please specify exact ID.");
                return;
            }

            var existingOrder = existingOrders[0];
            Console.WriteLine("Existing order details:");
            Console.WriteLine(existingOrder);

            // 创建修改后的订单
            Console.WriteLine("\nEnter new details:");

            // 选择客户
            Console.WriteLine("Available Customers:");
            for (int i = 0; i < customers.Count; i++)
            {
                Console.WriteLine($"{i + 1}. {customers[i]}");
            }
            Console.Write("Select customer (number): ");
            int custIndex = int.Parse(Console.ReadLine()) - 1;
            var customer = customers[custIndex];

            var modifiedOrder = new Order(existingOrder.OrderId, customer, existingOrder.OrderDate);

            // 添加订单明细
            bool addMore = true;
            while (addMore)
            {
                Console.WriteLine("\nAvailable Products:");
                for (int i = 0; i < products.Count; i++)
                {
                    Console.WriteLine($"{i + 1}. {products[i]}");
                }
                Console.Write("Select product (number): ");
                int prodIndex = int.Parse(Console.ReadLine()) - 1;
                var product = products[prodIndex];

                Console.Write("Enter quantity: ");
                int quantity = int.Parse(Console.ReadLine());

                modifiedOrder.AddDetail(new OrderDetail(product, quantity));

                Console.Write("Add another product? (y/n): ");
                addMore = Console.ReadLine().ToLower() == "y";
            }

            orderService.ModifyOrder(modifiedOrder);
            Console.WriteLine("Order modified successfully.");
        }

        static void QueryOrders()
        {
            Console.WriteLine("\n--- Query Orders ---");
            Console.WriteLine("1. By Order ID");
            Console.WriteLine("2. By Product Name");
            Console.WriteLine("3. By Customer Name");
            Console.WriteLine("4. By Amount Range");
            Console.Write("Select query type: ");

            int queryType = int.Parse(Console.ReadLine());

            List<Order> result = null;

            switch (queryType)
            {
                case 1:
                    Console.Write("Enter Order ID (or part of it): ");
                    string orderId = Console.ReadLine();
                    result = orderService.QueryByOrderId(orderId);
                    break;
                case 2:
                    Console.Write("Enter Product Name (or part of it): ");
                    string productName = Console.ReadLine();
                    result = orderService.QueryByProductName(productName);
                    break;
                case 3:
                    Console.Write("Enter Customer Name (or part of it): ");
                    string customerName = Console.ReadLine();
                    result = orderService.QueryByCustomer(customerName);
                    break;
                case 4:
                    Console.Write("Enter minimum amount: ");
                    decimal minAmount = decimal.Parse(Console.ReadLine());
                    Console.Write("Enter maximum amount: ");
                    decimal maxAmount = decimal.Parse(Console.ReadLine());
                    result = orderService.QueryByAmountRange(minAmount, maxAmount);
                    break;
                default:
                    Console.WriteLine("Invalid query type.");
                    return;
            }

            Console.WriteLine("\nQuery Results:");
            foreach (var order in result)
            {
                Console.WriteLine(order);
                Console.WriteLine("---------------------");
            }
        }

        static void ListAllOrders()
        {
            Console.WriteLine("\n--- All Orders ---");
            var orders = orderService.GetAllOrders();

            if (orders.Count == 0)
            {
                Console.WriteLine("No orders found.");
                return;
            }

            foreach (var order in orders)
            {
                Console.WriteLine(order);
                Console.WriteLine("---------------------");
            }
        }

        static void SortOrders()
        {
            Console.WriteLine("\n--- Sort Orders ---");
            Console.WriteLine("1. By Order ID (default)");
            Console.WriteLine("2. By Order Date");
            Console.WriteLine("3. By Total Amount");
            Console.Write("Select sort option: ");

            int sortOption = int.Parse(Console.ReadLine());

            switch (sortOption)
            {
                case 1:
                    orderService.SortOrders();
                    Console.WriteLine("Orders sorted by Order ID.");
                    break;
                case 2:
                    orderService.SortOrders((o1, o2) => o1.OrderDate.CompareTo(o2.OrderDate));
                    Console.WriteLine("Orders sorted by Order Date.");
                    break;
                case 3:
                    orderService.SortOrders((o1, o2) => o1.TotalAmount.CompareTo(o2.TotalAmount));
                    Console.WriteLine("Orders sorted by Total Amount.");
                    break;
                default:
                    Console.WriteLine("Invalid sort option.");
                    break;
            }
        }

        static void ExportOrders()
        {
            Console.Write("\nEnter file path to export orders: ");
            string filePath = Console.ReadLine();

            orderService.ExportToFile(filePath);
            Console.WriteLine("Orders exported successfully.");
        }
    }
    
}
